package nlppatents.util;

import java.util.ArrayList;
import java.util.HashMap;

public class POS 
{
	public static HashMap<String, POS> posMap = null;
	public static ArrayList<POS> posList = null;
	public static POS get(String label)
	{
		POS p = posMap.get(label);
		
		if(p == null) 
		{
			p = POS.word; //posMap.get("WORD");
			put(label, p);
			System.err.println("!!!  Unknown label encountered: \"" + label + "\"");
		}
			
		return p;
	}
	
	// saves me a few tedious keystrokes
	public static void put(String key, POS value)
	{
		posMap.put(key, value);
	}
	
	public static void init()
	{
		// create our POS catalogue
		posMap = new HashMap<String, POS>();
		POS p = null;
		
		// COORDINATING CONJUNCTION
		// Left by itself for our uses
		p = new POS("CC", "Coordinating Conjunction");
		put("CC", p);
		POS.cc = p;
		
		// DETERMINER
		// Clusters with following word (NP, VP, or PP), or is treated as a WORD phrase if cannot be clustered 
		p = new POS("DT", "Determinter");
		put("DT", p);
		// PDT's examples: all, both, half, many, nary, quite, rather, such
		put("PDT", p); 
		POS.det = p;
		
		
		// EXISTENTIAL THERE is under VERBS
		//put("EX", new POS("EX", "Existential there"));
		
		// FW is under WORD
		
		/* PREPOSITIONAL PHRASES
		 * When it prepends Nouns:
		 *		Clusters with Nouns
		 * When it prepends Verbs:
		 *		Clusters with Verbs
		 * When it's alone
		 *		Classified as a WORD
		 */
		// PREPOSITIONS
		p = new POS("IN", "Preposition or Subordinating Conjunction");
		put("IN", p);
		POS.prep = p;
		
		// ADJECTIVES
		p = new POS("JJ", "Adjective");
		put("JJ", p);
		put("JJR", p);
		put("JJS", p);
		POS.adj = p;
		
		// LIST ITEM MARKERS - useful for claims section
		p = new POS("LS", "List item marker");
		put("LS", p);
		POS.ls = p;
		
		// MD is under VB
		
		// NOUNS
		p = new POS("NN", "Noun");
		put("NN", p);
		put("NNS", p);
		put("NNP", p);
		put("NNPS", p);
		put("PRP", p);
		put("PRP$", p);
		POS.noun = p;
		
		// PRP (prounoun) under NN
		//p = new POS("PRP", "Preposition");
		
		// PDT is under DT
		
		// POS (" 's ")... don't know how I will handle you
		// Temporarily under WORD
		
		// PRP & PRP$ under NP
		
		// ADVERBS
		// Clusters with verbs except when there are no following verbs, then it's a WORD phrase
		//p = new POS("RB", "Adverb");
		// EDIT:  added to verbs!
		
		// RP is under WORD
		// SYM is under WORD
		
		// THE WORD "to"
		// When it clusters with verbs:
		//		TO <verb phrase>
		// When it acts like a preposition:
		//		TO <noun phrase>
		p = new POS("TO", "The word 'to'");
		put("TO", p);
		POS.to = p;
		
		// VERBS
		p = new POS("VB", "Verb");
		put("VB", p);
		put("VBD", p);
		put("VBG", p);
		put("VBN", p);
		put("VBP", p);
		put("VBZ", p);
		// Modals (MD): Always clusters with following VB for our purposes
		// examples: will/MD be/VB, can/MD be/VB, can/MD decrease/VB 
		put("MD", p);
		// Existential "there" (EX): Always clusters with following VB for our purposes
		// examples: there/EX has/VBZ, there/EX are/VBP, there/EX can/MD be/VB (look at that, even got a modal in there :D)
		put("EX", p); 
		// Particles (RP): Always clusters with leading verbs for our purposes
		// examples: assist/VB in/RP, point/VB out/RP, shuts/VBZ off/RP
		put("RP", p); 
		// which, that "when it is used as a relative pronoun"
		// Clusters with Verbs frequently enough that can be classifed as such for our
		// purposes (I have yet to find an exception where noun-phrases would greatly benefit)
		put("WDT", p); 
		// adverbs:  always cluster with verbs
		put("RB", p);
		put("RBR", p);
		put("RBS", p);
		POS.verb = p;
		
		// WDT is under VB
		
		// WORDS
		// Clusters with nothing but words to make WORD phrases (basically ignored chunks);
		p = new POS("WORD", "Catch-all POS");
		put("WORD", p);
		put("FW", p); // our POST likes to classify things like i.e. and etc as FW's
		put("POS", p); // ?? Temporary ??
		put("SYM", p); // yet to find this tag used, so I will treat it as a word
		put("WP", p);
		put("WP$", p);
		put("WRB", p);
		POS.word = p;
		
		// These POS tags have been excluded purposely
		//put("FW", new POS("FW", "Foreign word"));
		//put("MD", new POS("MD", "Modal"));
		
		p = new POS(".", "Period");
		put(".", p);
		POS.period = p;
		
		p = new POS(",", "Comma");
		put(",", p);
		POS.comma = p;
	}
	
	/*
	 * commonly used POS types
	 */
	
	public static POS cc; // coordinating conjunction
	public static POS det; // determiner
	public static POS prep; // preposition
	public static POS adj; // adjective
	public static POS ls; // list item marker
	public static POS noun;
	public static POS to; // the word "to"
	public static POS verb;
	public static POS word;
	
	public static POS period;
	public static POS comma;
	
	public String label;  // screw encapsulation, this is faster for comparisons
	public String description;
	public POS(String label, String description)
	{
		this.label = label.toUpperCase();
		this.description = description;
	}
}
